package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private DishService dishService;

    @Override
    public void saveWithDish(SetmealDto setmealDto) {
        //添加基本信息
        this.save(setmealDto);
        /*
            添加复合信息
         */
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes(); //取出套餐菜品集合
        //从复合集合信息setmealDishes里面取出套餐菜品setmealDish
        List<SetmealDish> setmealDishList = setmealDishes.stream().map((setmealDish) -> {
            //把复合信息setmealDishes里的id 赋值给 setmealDish套餐菜品
            setmealDish.setSetmealId(setmealDto.getId());
            return setmealDish;
        }).collect(Collectors.toList());

        setmealDishService.saveBatch(setmealDishList);

    }

    /**
     * 批量删除（开启事务）
     * @param ids
     */
    @Transactional
    @Override
    public void removeWithDish(List<Long> ids) {
        /*
        该业务层方法具体的逻辑为:
        A. 查询该批次套餐中是否包含正在售卖的套餐, 如果存在, 不允许删除
        B. 删除套餐数据
        C. 删除套餐关联的菜品数据
         */
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();
        //设置条件   where id in (ids) and status = 1
        lqw.in(Setmeal::getId, ids)
           .eq(Setmeal::getStatus, 1);
        int count = this.count(lqw); //获取按条件查询到的数量
        if (count > 0) {//如果不能删除，抛出一个业务异常
            throw new CustomException("套餐正在售卖中，不能删除");
        }
        //如果可以删除，先删除套餐表中的数据---setmeal
        this.removeByIds(ids);
        //再删除复合关系表  delete from setmeal_dish where setmeal_id in (1,2,3)
        LambdaQueryWrapper<SetmealDish> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(SetmealDish::getSetmealId,ids);
        //删除关系表中的数据----setmeal_dish
        setmealDishService.remove(lambdaQueryWrapper);
    }

    /**
     * 根据id查询  用于修改套餐时回显数据
     * @param id
     * @return
     */
    @Override
    public SetmealDto getByIdWithDish(Long id) {
        Setmeal setmeal = this.getById(id); //查询基础的套餐信息
        SetmealDto setmealDto = new SetmealDto();//创建一个复合信息对象
        BeanUtils.copyProperties(setmeal,setmealDto); //转存数据

        //根据套餐和菜品的关系表查询数据
        LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SetmealDish::getSetmealId,id);
        List<SetmealDish> dishes = setmealDishService.list(lqw); //根据套餐id 查询包含的菜品集合
        setmealDto.setSetmealDishes(dishes); //把查询到的菜品集合赋值给复合表
        return setmealDto; //返回复合表
    }

    /**
     * 修改套餐
     * @param setmealDto
     */
    @Override
    @Transactional
    public void updateWithDish(SetmealDto setmealDto) {
        this.updateById(setmealDto); //此时的this是：SetmealService，先根据复合类修改基础信息
        /*
            然后修改的是SetmealDish表
            业务处理逻辑也是先删以前存在的 再添加传过来的
         */
        LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SetmealDish::getSetmealId,setmealDto.getId()); //复合类里的SetmealId
        //删除
        setmealDishService.remove(lqw); //根据SetmealId 删除SetmealDish表(原来的菜品)

        //添加
        List<SetmealDish> dishes = setmealDto.getSetmealDishes(); //获取到传过来的复合信息里的菜品列表
        dishes = dishes.stream().map((dish) -> { //dish:每个菜品
            dish.setSetmealId(setmealDto.getId()); //套餐id赋值给菜品的SetmealId属性
            return dish; //此时每个菜品就有了套餐属性
        }).collect(Collectors.toList()); //菜品集合更新完毕

        //循环修改
        setmealDishService.saveBatch(dishes);
    }

    @Override
    public List<DishDto> select(Long id) {
        LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SetmealDish::getSetmealId,id);
        List<SetmealDish> setmealDishes = setmealDishService.list(lqw);
        List<DishDto> dishDtos = setmealDishes.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            dishDto.setCopies(item.getCopies());  //设置数量
            Long dishId = item.getDishId();
            LambdaQueryWrapper<Dish> lqw2 = new LambdaQueryWrapper<>();
            lqw2.eq(Dish::getId, dishDto);
            Dish dishById = dishService.getById(dishId);
            BeanUtils.copyProperties(dishById, dishDto);
            return dishDto;
        }).collect(Collectors.toList());

        return dishDtos;
    }

   /* @Override
    public List<SetmealDto> selectSetmealDto(Long id) {
        log.info("id====>:{}",id);  //传过来的是SetmealId
        LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SetmealDish::getSetmealId,id);
        //根据SetmealId 查询到setmealDish集合
        List<SetmealDish> setmealDishList = setmealDishService.list(lqw);
        List<SetmealDto> dtos = setmealDishList.stream().map((item) -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(item, setmealDto); //拷贝套餐信息
            //  setmealDto.setCategoryName(item.); //设置分类名称
            return setmealDto;
        }).collect(Collectors.toList());

        return dtos;
    }*/
}
